import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    favorites: []
  },
  mutations: {
    SET_FAVORITES(state, favorites) {
      state.favorites = favorites
    }
  },
  actions: {
    loadFavorites({ commit }) {
      const favorites = localStorage.getItem('favorites')
      if (favorites) {
        commit('SET_FAVORITES', JSON.parse(favorites))
      }
    },
    addFavorite({ commit, state }, movieId) {
      const newFavorites = [...state.favorites, movieId]
      localStorage.setItem('favorites', JSON.stringify(newFavorites))
      commit('SET_FAVORITES', newFavorites)
    },
    removeFavorite({ commit, state }, movieId) {
      const newFavorites = state.favorites.filter(id => id !== movieId)
      localStorage.setItem('favorites', JSON.stringify(newFavorites))
      commit('SET_FAVORITES', newFavorites)
    }
  },
  getters: {
    getFavorites: state => state.favorites
  }
})
```

d:\movie\frontend\src\views\Favorites.vue
```vue
<<<<<<< SEARCH
<script>
import axios from 'axios'

export default {
  name: 'Favorites',
  data() {
    return {
      favoriteMovies: [],
      loading: true,
      favorites: []
    }
  },
  mounted() {
    this.loadFavorites()
    this.fetchFavoriteMovies()
  },
  methods: {
    loadFavorites() {
      const favorites = localStorage.getItem('favorites')
      if (favorites) {
        this.favorites = JSON.parse(favorites)
      }
    },
    fetchFavoriteMovies() {
      if (this.favorites.length === 0) {
        this.favoriteMovies = []
        this.loading = false
        return
      }
      
      // 并行获取所有收藏的电影
      const requests = this.favorites.map(id => 
        axios.get(`http://localhost:8080/api/movies/${id}`)
      )
      
      Promise.all(requests)
        .then(responses => {
          this.favoriteMovies = responses.map(res => res.data)
          this.loading = false
        })
        .catch(error => {
          console.error('Error fetching favorite movies:', error)
          this.loading = false
        })
    },
    toggleFavorite(movieId) {
      const index = this.favorites.indexOf(movieId)
      if (index > -1) {
        this.favorites.splice(index, 1)
        localStorage.setItem('favorites', JSON.stringify(this.favorites))
        this.fetchFavoriteMovies()
      }
    },
    truncateText(text, maxLength) {
      if (text.length <= maxLength) {
        return text
      }
      return text.substr(0, maxLength) + '...'
    },
    formatDuration(minutes) {
      const hours = Math.floor(minutes / 60)
      const mins = minutes % 60
      if (hours > 0) {
        return `${hours}h ${mins}m`
      }
      return `${mins}m`
    }
  }
}
</script>
<script>
import axios from 'axios'
import store from '../store'

export default {
  name: 'Favorites',
  data() {
    return {
      favoriteMovies: [],
      loading: true
    }
  },
  mounted() {
    this.fetchFavoriteMovies()
  },
  methods: {
    fetchFavoriteMovies() {
      const favorites = store.getters.getFavorites
      
      if (favorites.length === 0) {
        this.favoriteMovies = []
        this.loading = false
        return
      }
      
      // 并行获取所有收藏的电影
      const requests = favorites.map(id => 
        axios.get(`http://localhost:8080/api/movies/${id}`)
      )
      
      Promise.all(requests)
        .then(responses => {
          this.favoriteMovies = responses.map(res => res.data)
          this.loading = false
        })
        .catch(error => {
          console.error('Error fetching favorite movies:', error)
          this.loading = false
        })
    },
    toggleFavorite(movieId) {
      store.dispatch('removeFavorite', movieId)
      this.fetchFavoriteMovies()
    },
    truncateText(text, maxLength) {
      if (text.length <= maxLength) {
        return text
      }
      return text.substr(0, maxLength) + '...'
    },
    formatDuration(minutes) {
      const hours = Math.floor(minutes / 60)
      const mins = minutes % 60
      if (hours > 0) {
        return `${hours}h ${mins}m`
      }
      return `${mins}m`
    }
  }
}
</script>
<template>
  <div class="favorites">
    <div class="jumbotron jumbotron-fluid">
      <div class="container">
        <h1 class="display-4">My Favorite Movies</h1>
        <p class="lead">Your personal collection of favorite movies.</p>
      </div>
    </div>
    
    <div class="container">
      <div v-if="loading" class="text-center my-5">
        <div class="spinner-border text-primary" role="status">
          <span class="sr-only">Loading...</span>
        </div>
        <p class="mt-2">Loading your favorites...</p>
      </div>
      
      <div v-else>
        <h2 class="mb-4">Favorite Movies ({{ favoriteMovies.length }})</h2>
        
        <div v-if="favoriteMovies.length === 0" class="text-center my-5">
          <div class="display-4 text-muted">💔</div>
          <h3 class="mt-3">No favorite movies yet</h3>
          <p class="lead">Start adding movies to your favorites from the movie list</p>
          <router-link to="/" class="btn btn-primary">Browse Movies</router-link>
        </div>
        
        <div v-else>
          <div class="row">
            <div class="col-lg-3 col-md-4 col-sm-6 mb-4" v-for="movie in favoriteMovies" :key="movie.id">
              <div class="card h-100">
                <img :src="movie.coverImageUrl || 'https://via.placeholder.com/300x400?text=No+Image'" 
                     class="card-img-top" 
                     :alt="movie.title"
                     style="height: 300px; object-fit: cover;">
                <div class="card-body d-flex flex-column">
                  <h5 class="card-title">{{ movie.title }} ({{ movie.year }})</h5>
                  <p class="card-text flex-grow-1">{{ truncateText(movie.description, 100) }}</p>
                  <div class="mb-2">
                    <span class="badge badge-primary">{{ movie.genre }}</span>
                    <span class="badge badge-success ml-1">{{ movie.rating }}/10</span>
                  </div>
                  <div class="mb-2">
                    <small class="text-muted">{{ formatDuration(movie.duration) }}</small>
                  </div>
                  <div class="mt-auto">
                    <router-link :to="'/movie/' + movie.id" class="btn btn-primary btn-sm">
                      Watch Now
                    </router-link>
                    <button @click="toggleFavorite(movie.id)" class="btn btn-sm btn-danger ml-2">
                      Remove ❤️
                    </button>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import axios from 'axios'

export default {
  name: 'Favorites',
  data() {
    return {
      favoriteMovies: [],
      loading: true,
      favorites: []
    }
  },
  mounted() {
    this.loadFavorites()
    this.fetchFavoriteMovies()
  },
  methods: {
    loadFavorites() {
      const favorites = localStorage.getItem('favorites')
      if (favorites) {
        this.favorites = JSON.parse(favorites)
      }
    },
    fetchFavoriteMovies() {
      if (this.favorites.length === 0) {
        this.favoriteMovies = []
        this.loading = false
        return
      }
      
      // 并行获取所有收藏的电影
      const requests = this.favorites.map(id => 
        axios.get(`http://localhost:8080/api/movies/${id}`)
      )
      
      Promise.all(requests)
        .then(responses => {
          this.favoriteMovies = responses.map(res => res.data)
          this.loading = false
        })
        .catch(error => {
          console.error('Error fetching favorite movies:', error)
          this.loading = false
        })
    },
    toggleFavorite(movieId) {
      const index = this.favorites.indexOf(movieId)
      if (index > -1) {
        this.favorites.splice(index, 1)
        localStorage.setItem('favorites', JSON.stringify(this.favorites))
        this.fetchFavoriteMovies()
      }
    },
    truncateText(text, maxLength) {
      if (text.length <= maxLength) {
        return text
      }
      return text.substr(0, maxLength) + '...'
    },
    formatDuration(minutes) {
      const hours = Math.floor(minutes / 60)
      const mins = minutes % 60
      if (hours > 0) {
        return `${hours}h ${mins}m`
      }
      return `${mins}m`
    }
  }
}
</script>

<style scoped>
/* 样式已移至全局样式文件 */
</style>